package com.candy.candycommon.utils;

import org.apache.commons.codec.Charsets;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author zhang.wenhan
 * @description
 * @date 2021年6月18日 下午2:47:51
 */
public class HttpPostUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpPostUtil.class);

    private static final Integer TIMEOUT = 120;

    public static String postXml(String url, String json, String encoding) {
        return doPost(url, json, "application/xml;charset=" + encoding, encoding);
    }

    public static String postText(String url, String json, String encoding) {
        return doPost(url, json, MediaType.TEXT_PLAIN_VALUE, encoding);
    }

    public static String postText(String url, String json) {
        return doPost(url, json, MediaType.TEXT_PLAIN_VALUE);
    }

    public static String doPost(String url, String json) {
        return doPost(url, json, MediaType.APPLICATION_JSON_VALUE);
    }

    public static String doPost(String url, String json, String mediaType) {
        return doPost(url, json, mediaType, Charsets.UTF_8.name());
    }

    public static String doPost(String url, String json, Map<String, String> header) {
        return doPost(url, json, MediaType.APPLICATION_JSON_VALUE, Charsets.UTF_8.name(), header);
    }

    public static String doPost(String url, String json, String mediaType, String encoding) {
        return doPost(url, json, mediaType, encoding, null);
    }

    public static String doPost(String url, String json, String mediaType, String encoding, Map<String, String> header) {
        String res = null;
        CloseableHttpResponse response = null;
        HttpPost post = new HttpPost(url);
        try {
            CloseableHttpClient client = HttpClientBuilder.create().setConnectionTimeToLive(TIMEOUT, TimeUnit.SECONDS)
                    .build();
            StringEntity entity = new StringEntity(json, encoding);
            entity.setContentEncoding(encoding);
            entity.setContentType(mediaType);
            post.setEntity(entity);
            if (header != null && header.size() > 0) {
                header.keySet().stream().forEach(key -> post.addHeader(key, header.get(key)));
            }
            response = client.execute(post);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new RuntimeException(EntityUtils.toString(response.getEntity()));
            }
            res = EntityUtils.toString(response.getEntity());
        } catch (RuntimeException e) {
            logger.error("执行http请求异常, url:" + url + " request:" + json, e);
            throw e;
        } catch (Exception e) {
            logger.error("执行http请求异常, url:" + url + " request:" + json, e);
            throw new RuntimeException(e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    logger.error("response 关闭异常url:" + url + " request:" + json, e);
                }
            }
        }
        return res;
    }

    public static String doGet(String url, Map<String, String> header) throws Exception {
        return doGet(url, Charsets.UTF_8.name(), header);
    }

    public static String doGet(String url, String encoding, Map<String, String> header) throws Exception {
        CloseableHttpResponse response = null;
        String res = null;
        try {
            CloseableHttpClient client = HttpClients.createDefault();
            HttpGet get = new HttpGet(url);
            if (header != null && header.size() > 0) {
                header.keySet().stream().forEach(key -> get.addHeader(key, header.get(key)));
            }
            response = client.execute(get);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new RuntimeException(EntityUtils.toString(response.getEntity()));
            }
            res = EntityUtils.toString(response.getEntity(), encoding);
        } catch (RuntimeException e) {
            logger.error("执行http请求异常, url:" + url, e);
            throw e;
        } catch (Exception e) {
            logger.error("执行http请求异常, url:" + url, e);
            throw new RuntimeException(e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                logger.error("response 关闭异常url:" + url, e);
            }
        }
        return res;
    }

}
